/*
 * Copyright 2010 Christopher Z. Collier
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package net.xorf.caveman.gui;

import java.awt.Component;
import java.io.File;
import java.util.prefs.Preferences;

import javax.swing.JFileChooser;
import javax.swing.filechooser.FileFilter;

/**
 * Some static methods that wrap <tt>JFileChooser</tt> and provide
 * conveniences for the file choosing needs of this application.
 * 
 * Extra functionality on top of <tt>JFileChooser</tt> provided:
 * <ul>
 *   <li>
 *   The ability to persist the last directory from which a file was selected
 *   to the user's preferences.  An identifying key can be passed to the
 *   chooser-opening methods.  This key will tie to a last-directory setting,
 *   so different last-used directories can be tied to different file choosers
 *   on the UI
 *   </li>
 * </ul>
 *
 * @author ccollier
 */
@SuppressWarnings("serial")
public final class EasyFileChooser extends JFileChooser {
    private static final String LASTDIR_PREF_KEY = "filechooser.lastdir";
    private static final String DEFAULT_CHOOSER_NAME = "default";
    
    private static Preferences prefs = Preferences.userRoot().node(
            EasyFileChooser.class.getPackage().getName().replace('.', '/'));
    
    private static File getLastDir(String chooserKey) {
        String lastDir = prefs.get(
                String.format("%s.%s", LASTDIR_PREF_KEY, chooserKey), null);
        
        //TODO: check for missing/invalid path
        return lastDir == null ? null : new File(lastDir);
    }
    
    private static void setLastDir(String chooserKey, File lastFile) {
        prefs.put(String.format("%s.%s", LASTDIR_PREF_KEY, chooserKey), lastFile.getAbsolutePath());
    }

    private final String chooserName;
    private final Component parent;
    
    public EasyFileChooser(Component parent, String chooserName) {
        super();
        
        this.chooserName = chooserName;
        this.parent = parent;
        
        setFileHidingEnabled(true);
        setAcceptAllFileFilterUsed(false);
        setCurrentDirectory(getLastDir(chooserName));
    }
    
    public EasyFileChooser(Component parent) {
        this(parent, DEFAULT_CHOOSER_NAME);
    }
    
    public File chooseSingleFile() {
        setMultiSelectionEnabled(false);
        
        if (showOpenDialog(parent) != JFileChooser.APPROVE_OPTION)
            return null;

        setLastDir(chooserName, getCurrentDirectory());
        return getSelectedFile();
    }
    
    public File[] chooseMultiFiles() {
        setMultiSelectionEnabled(true);
        
        if (showOpenDialog(parent) != JFileChooser.APPROVE_OPTION)
            return null;

        setLastDir(chooserName, getCurrentDirectory());
        return getSelectedFiles();
    }
    
    public EasyFileChooser addFilter(String suffixSpec, String description) {
        String[] suffixes = suffixSpec.split("[ ,;\\|]");
        addChoosableFileFilter(new FileNameSuffixFilter(suffixes, description));
        return this;
    }
    
    class FileNameSuffixFilter extends FileFilter {
        private final String[] suffixes;
        private final String description;
        
        public FileNameSuffixFilter(String[] suffixes, String description) {
            this.suffixes = suffixes;
            this.description = description;
        }
        
        @Override
        public boolean accept(File file) {
            String fileName = file.getName();
            
            for (String s : suffixes) {
                if (fileName.endsWith(s))
                    return true;
            }
            return false;
        }

        @Override
        public String getDescription() {
            return description;
        }
    }
}
